package com.liuyi.netty.im.server.handle.pipeline;

import cn.hutool.core.util.StrUtil;
import com.liuyi.netty.im.commons.codes.CodeConst;
import com.liuyi.netty.im.commons.codes.data.DataEvent;
import com.liuyi.netty.im.commons.codes.data.DataLogin;
import com.liuyi.netty.im.commons.codes.data.LimData;
import com.liuyi.netty.im.commons.codes.data.event.Message;
import com.liuyi.netty.im.commons.codes.data.event.Session;
import com.liuyi.netty.im.commons.codes.data.event.message.playload.Playload;
import com.liuyi.netty.im.commons.codes.unusual.LimException;
import com.liuyi.netty.im.commons.enums.UserLineStatus;
import com.liuyi.netty.im.server.config.LimController;
import com.liuyi.netty.im.server.handle.service.model.UserAuthResult;
import com.liuyi.netty.im.server.handle.storage.ChannelStorage;
import com.liuyi.netty.im.server.handle.storage.User;
import com.liuyi.netty.im.server.util.ImHelp;
import com.liuyi.netty.im.server.util.ImUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 连接处理
 *
 * @author Mr.Fmy
 * @since 2021-11-27
 */
@Slf4j
public class LoginProcessor extends AbstractProessor {


    public LoginProcessor(LimController controller) {
        super(controller);
    }

    @Override
    public void processor(ChannelHandlerContext ctx, LimData data) {
        final Channel channel = ctx.channel();
        DataLogin msg = (DataLogin) data;
        if (msg == null || StrUtil.isEmpty(msg.getSign())) {
            //关闭连接
            channel.close();
            return;
        }
        UserAuthResult userAuthResult = super.getRelationChainService().login(msg.getSign());
        if (userAuthResult == null) {
            //签名不合法
            return;
        }
        User user = super.getUserStorage().getUser(userAuthResult.getUserId(), userAuthResult.getDevice());
        if (user != null && user.getUserLineStatus().equals(UserLineStatus.ON)) {
            //这里只是标记其下线状态，并不会close连接
            ImHelp.replaced(userAuthResult.getUserId(), userAuthResult.getDevice());
        }
        user = super.getUserStorage().onLine(channel, msg.getSign(), userAuthResult.getUserId(), userAuthResult.getDevice());
        if (user == null) {
            throw new LimException("login fail sign：" + msg.getSign());
        }
        //储存channel
        ChannelStorage.add(channel, user);
        //发送就绪事件
        ImUtil.send(channel, new DataEvent(CodeConst.Event.READY, CodeConst.EventToType.CHANNELID, channel.id().asLongText(), null));
        //发送会话列表刷新事件
        List<Session> sessions = getSessionService().listByUserId(user.getUserId());
        ImUtil.send(channel, new DataEvent(CodeConst.Event.SESSION_LIST_REFRESH, CodeConst.EventToType.CHANNELID, channel.id().asLongText(), sessions));
        //未发送消息发送
        List<Message<? extends Playload>> messages = super.getMessageService().listNotSendByUser(user.getUserId());
        if (messages != null) {
            messages.forEach(ImUtil::sendMessage);
        }
    }
}
